/*
* // +-------------------------------------------------------------------------------------------------
* // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
* // +-------------------------------------------------------------------------------------------------
* // |                             独在异乡为异客         每逢佳节倍思亲
* // +-------------------------------------------------------------------------------------------------
* // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
* // +-------------------------------------------------------------------------------------------------
*/

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------

package wang.encoding.mroot.admin.common.controller


import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.plugins.Page
import com.google.code.kaptcha.Constants
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.ApplicationContext
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.mvc.support.RedirectAttributes
import wang.encoding.mroot.admin.common.constant.ConfigConst
import wang.encoding.mroot.admin.common.constant.DatabaseConst
import wang.encoding.mroot.admin.common.constant.Global
import wang.encoding.mroot.admin.common.task.ControllerAsyncTask
import wang.encoding.mroot.admin.common.util.ShiroSessionUtil
import wang.encoding.mroot.common.business.Profile
import wang.encoding.mroot.common.business.ResultData
import wang.encoding.mroot.common.config.AesManageConfiguration
import wang.encoding.mroot.common.config.DigestManageConfiguration
import wang.encoding.mroot.common.constant.ShareConst
import wang.encoding.mroot.common.controller.BaseController
import wang.encoding.mroot.common.util.ArrayUtil
import wang.encoding.mroot.common.util.HibernateValidationUtil
import wang.encoding.mroot.common.util.HttpRequestUtil
import wang.encoding.mroot.model.entity.system.Config
import wang.encoding.mroot.model.entity.system.Rule
import wang.encoding.mroot.model.entity.system.User
import wang.encoding.mroot.model.enums.RuleTypeEnum
import wang.encoding.mroot.service.system.RuleService
import wang.encoding.mroot.task.BusinessAsyncTask
import java.math.BigInteger
import java.text.SimpleDateFormat
import java.util.*
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpSession


/**
 * 后台基类控制器
 *
 * @author ErYang
 */
open class BaseAdminController : BaseController() {

    @Value(value = "\${server.servlet.contextPath}")
    protected lateinit var contextPath: String

    @Autowired
    private lateinit var ruleService: RuleService

    @Autowired
    protected lateinit var configProperties: ConfigConst

    @Autowired
    protected lateinit var digestManageConfiguration: DigestManageConfiguration

    @Autowired
    protected lateinit var aesManageConfiguration: AesManageConfiguration

    @Autowired
    protected lateinit var applicationContext: ApplicationContext

    @Autowired
    private lateinit var profile: Profile

    @Autowired
    protected lateinit var controllerAsyncTask: ControllerAsyncTask

    @Autowired
    private lateinit var databaseConst: DatabaseConst

    @Autowired
    protected lateinit var httpRequestUtil: HttpRequestUtil

    @Autowired
    private lateinit var shareProperties: ShareConst

    @Autowired
    protected lateinit var businessAsyncTask: BusinessAsyncTask

    @Value(value = "\${upload.resources-path}")
    protected lateinit var uploadResourcesPath: String

    // -------------------------------------------------------------------------------------------------

    companion object {

        /**
         * 下划线
         */
        const val UNDER_LINE: String = "_"
        /**
         * 错误页面地址
         */
        private const val ERROR404_URL: String = "/error/404"
        /**
         * html br 标签
         */
        private const val HTML_BR: String = "<br>"
        /**
         * statusStr 状态参数名称
         */
        private const val STATUS_STR_PARAMETER_NAME: String = "statusStr"

        /**
         * id[] 集合参数名称
         */
        private const val ID_ARRAY_PARAMETER_NAME: String = "id[]"
        /**
         * 页面 分页 名称
         */
        const val VIEW_PAGE_NAME: String = "page"
        /**
         *  id 标识名称
         */
        const val ID_NAME: String = "id"

        /**
         * 错误提示语 名称标识
         */
        const val MESSAGE_ERROR_NAME: String = "message.info.error"
        /**
         * 标识存在 名称标识
         */
        const val MESSAGE_NAME_EXIST_NAME: String = "message.name.exist"
        /**
         * 标题存在 名称标识
         */
        const val MESSAGE_TITLE_EXIST_NAME: String = "message.title.exist"
        /**
         * 添加成功提示语 名称标识
         */
        const val MESSAGE_ADD_INFO_SUCCEED_NAME: String = "message.add.info.succeed"
        /**
         * 添加失败提示语 名称标识
         */
        const val MESSAGE_ADD_INFO_FAIL_NAME: String = "message.add.info.fail"
        /**
         * 编辑成功提示语 名称标识
         */
        const val MESSAGE_EDIT_INFO_SUCCEED_NAME: String = "message.edit.info.succeed"
        /**
         * 编辑失败提示语 名称标识
         */
        const val MESSAGE_EDIT_INFO_FAIL_NAME: String = "message.edit.info.fail"
        /**
         * 删除成功提示语 名称标识
         */
        const val MESSAGE_DELETE_INFO_SUCCEED_NAME: String = "message.delete.info.succeed"
        /**
         * 删除失败提示语 名称标识
         */
        const val MESSAGE_DELETE_INFO_FAIL_NAME: String = "message.delete.info.fail"
        /**
         * 恢复成功提示语 名称标识
         */
        const val MESSAGE_RECOVER_INFO_SUCCEED_NAME: String = "message.recover.info.succeed"
        /**
         * 恢复失败提示语 名称标识
         */
        const val MESSAGE_RECOVER_INFO_FAIL_NAME: String = "message.recover.info.fail"
        /**
         * 清空成功提示语 名称标识
         */
        const val MESSAGE_TRUNCATE_INFO_SUCCEED_NAME: String = "message.truncate.info.succeed"
        /**
         * 清空失败提示语 名称标识
         */
        const val MESSAGE_TRUNCATE_INFO_FAIL_NAME: String = "message.truncate.info.fail"
        /**
         * 生成成功提示语 名称标识
         */
        const val MESSAGE_GENERATE_INFO_SUCCEED_NAME: String = "message.generate.info.succeed"
        /**
         * 生成失败提示语 名称标识
         */
        const val MESSAGE_GENERATE_INFO_FAIL_NAME: String = "message.generate.info.fail"
        /**
         * 默认视图目录
         */
        private const val DEFAULT_VIEW: String = "/default"
        /**
         * 重定向标识
         */
        protected const val REDIRECT_NAME: String = "redirect:"
        /**
         * 上个请求变量名称
         */
        protected const val REFERER_URL_NAME: String = "refererUrl"
        /**
         * 面包屑菜单变量
         *
         */
        private const val BREAD_CRUMB_NAME: String = "breadcrumb"
        private const val BREAD_CRUMB_URL_NAME: String = "breadcrumbUrl"
        private const val BREAD_CRUMB_MENU_NAME: String = "breadcrumbMenu"
        private const val BREAD_CRUMB_CHILE_NAME: String = "breadcrumbChile"
        private const val BREAD_CRUMB_TITLE_NAME: String = "breadcrumbTitle"
        private const val HEAD_TITLE_NAME: String = "headTitle"
        /**
         * 页面地址
         */
        const val INDEX_URL_NAME: String = "index"
        private const val INDEX_URL: String = "/index"

        private const val ADD_URL_NAME: String = "add"
        private const val ADD_URL: String = "/add"

        private const val ADD_CHILDREN_URL_NAME: String = "addChildren"
        private const val ADD_CHILDREN_URL: String = "/addChildren"

        private const val SAVE_URL_NAME: String = "save"
        private const val SAVE_URL: String = "/save"

        private const val EDIT_URL_NAME: String = "edit"
        private const val EDIT_URL: String = "/edit"

        private const val UPDATE_URL_NAME: String = "update"
        private const val UPDATE_URL: String = "/update"

        private const val VIEW_URL_NAME: String = "view"
        private const val VIEW_URL: String = "/view"

        private const val DELETE_URL_NAME: String = "delete"
        private const val DELETE_URL: String = "/delete"

        private const val DELETE_BATCH_URL_NAME: String = "deleteBatch"
        private const val DELETE_BATCH_URL: String = "/deleteBatch"

        private const val GENERATE_URL_NAME: String = "generate"
        private const val GENERATE_URL: String = "/generate"

        private const val MODEL_NAME: String = "model"
        private const val MODEL_URL_NAME: String = "modelUrl"
        // nav 地址
        const val NAV_INDEX_URL_NAME: String = "navIndex"
        /**
         * 授权
         */
        private const val AUTHORIZATION_URL_NAME: String = "authorization"
        private const val AUTHORIZATION_URL: String = "/authorization"
        /**
         * 保存授权
         */
        private const val AUTHORIZATION_SAVE_URL_NAME: String = "authorizationSave"
        private const val AUTHORIZATION_SAVE_URL: String = "/authorizationSave"
        /**
         * 回收站
         */
        private const val RECYCLE_BIN_URL_NAME: String = "recycleBin"
        private const val RECYCLE_BIN_URL: String = "/recycleBin"
        /**
         * 恢复
         */
        private const val RECOVER_URL_NAME: String = "recover"
        private const val RECOVER_URL: String = "/recover"

        private const val RECOVER_BATCH_URL_NAME: String = "recoverBatch"
        private const val RECOVER_BATCH_URL: String = "/recoverBatch"
        /**
         * 更新密码
         */
        private const val UPDATE_PASSWORD_URL_NAME: String = "updatePassword"
        private const val UPDATE_PASSWORD_URL: String = "/updatePassword"
        /**
         * 更新昵称
         */
        private const val UPDATE_NICK_NAME_URL_NAME: String = "updateNickName"
        private const val UPDATE_NICK_NAME_URL: String = "/updateNickName"

        /**
         * 清空
         */
        private const val TRUNCATE_URL_NAME: String = "truncate"
        private const val TRUNCATE_URL: String = "/truncate"
        /**
         * 日期格式
         */
        val DATE_FORMAT = SimpleDateFormat("yyyyMMdd")
        /**
         * 上传文章图片的地址
         */
        const val ARTICLE_UPLOAD_PATH_URL: String = "assets/img/article/"
        /**
         * 运行
         */
        private const val RUN_URL_NAME: String = "run"
        private const val RUN_URL: String = "/run"
        /**
         * 暂停
         */
        private const val PAUSE_URL_NAME: String = "pause"
        private const val PAUSE_URL: String = "/pause"
        /**
         * 恢复
         */
        private const val RESUME_URL_NAME: String = "resume"
        private const val RESUME_URL: String = "/resume"
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 创建视图
     *
     * @param view 视图地址
     * @return String 视图地址
     */
    protected fun initView(view: String): String {
        return DEFAULT_VIEW + view
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 创建 url 地址
     *
     * @param url url 地址
     * @return String url 地址
     */
    protected fun initUrl(url: String): String {
        return "$contextPath/$url"
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 根据模块设置 url 地址、页面标题
     * @param url 地址
     * @param model 模块
     * @param request HttpServletRequest
     */
    protected fun initViewTitleAndModelUrl(url: String, model: String, request: HttpServletRequest) {
        initViewTitle(url, request)
        initModelUrl(model, request)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 设置分页
     *
     * @param request HttpServletRequest
     *
     * @return Page<T>
     */
    protected fun <T> initPage(request: HttpServletRequest): Page<T> {
        var index = 1
        val size: Int
        // 得到数据库配置的分页条数
        val config: Config? = Global.getConfigByName(databaseConst.adminPageSizeName)
        size = if (null == config || null == config.value?.toIntOrNull() || 0 >= config.value!!.toInt()) {
            configProperties.adminPageSize.toInt()
        } else {
            config.value!!.toInt()
        }

        val pageNumber: String? = request.getParameter("p")
        if (pageNumber != null) {
            if (pageNumber.isNotBlank()) {
                index = pageNumber.toInt()
            }
        }
        return Page(index, size)
    }

    // -------------------------------------------------------------------------------------------------


    /**
     * 添加失败 Flash 提示信息
     * 使用 addFlashAttribute 参数不会出现在url地址栏中
     *
     * 页面通过 ${failMessage} 获取
     *
     * @param messages messages 信息
     */
    protected fun addFailMessage(redirectAttributes: RedirectAttributes,
                                 vararg messages: String) {
        val sb = StringBuilder()
        for (message: String in messages) {
            sb.append(message).append(if (1 < messages.size) HTML_BR else "")
        }
        redirectAttributes.addFlashAttribute(configProperties.failMessageName, sb.toString())
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 添加失败 Flash 集合提示信息
     * 使用 addFlashAttribute 参数不会出现在url地址栏中
     *页面通过 ${failListMessage} 获取
     * @param linkedList LinkedList<String> 信息 不是 i18n信息
     */
    private fun addFailMessage(redirectAttributes: RedirectAttributes,
                               linkedList: LinkedList<String>) {
        redirectAttributes.addFlashAttribute(configProperties.failMessageListName, linkedList)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 添加 Hibernate Validation 提示信息
     *
     * @param  result String 信息
     *
     * @return String
     */
    private fun initResult2HibernateValidation(result: String): String {
        val msgArray: Array<String>? = convertStrToArray(result)
        return if (null != msgArray && msgArray.isNotEmpty()) {
            val sb = StringBuilder()
            for (message: String in msgArray) {
                sb.append(localeMessageSourceConfiguration.getMessage(message))
                        .append(if (1 < msgArray.size) HTML_BR else "")
            }
            localeMessageSourceConfiguration.getMessage(sb.toString())
        } else {
            localeMessageSourceConfiguration.getMessage(result)
        }
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建 Validation 验证信息
     *
     * @param redirectAttributes       RedirectAttributes
     * @param result       String 验证信息 i18n 名称
     */
    private fun initResult2Validation(redirectAttributes: RedirectAttributes, result: String) {
        val msgArray: Array<String>? = convertStrToArray(result)

        if (null != msgArray && msgArray.isNotEmpty()) {
            val list = LinkedList<String>()
            msgArray.mapTo(list) { localeMessageSourceConfiguration.getMessage(it) }
            this.addFailMessage(redirectAttributes, list)
        } else {
            this.addFailMessage(redirectAttributes, localeMessageSourceConfiguration.getMessage(result))
        }
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 根据模块创建模块重定向地址
     * 不包括 contextPath
     *
     * @param url       url
     * @return 重定向地址
     */
    protected fun initRedirectUrl(url: String): String {
        return REDIRECT_NAME + url
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建错误重定向地址
     *
     * @return 重定向地址
     */
    protected fun initErrorRedirectUrl(): ModelAndView {
        return ModelAndView(REDIRECT_NAME + ERROR404_URL)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建 查询信息 ModelAndView
     *
     * @param modelAndView       ModelAndView
     * @param redirectAttributes       RedirectAttributes
     * @param url       String
     * @return ModelAndView 跳转到页面
     */
    protected fun initValidationResult2Get(modelAndView: ModelAndView,
                                           redirectAttributes: RedirectAttributes,
                                           url: String): ModelAndView {
        this.initResult2Validation(redirectAttributes, MESSAGE_ERROR_NAME)
        modelAndView.viewName = this.initRedirectUrl(url)
        return modelAndView
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建 返回错误信息 JSONObject
     *
     * @return JSONObject
     */
    protected fun initReturnErrorJSONObject(): JSONObject {
        val resultData: ResultData = ResultData.fail(configProperties.messageName,
                localeMessageSourceConfiguration.getMessage(MESSAGE_ERROR_NAME))
        return resultData.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建失败检查信息 JSONObject
     *
     * @return JSONObject
     */
    protected fun initErrorCheckJSONObject(): JSONObject {
        val resultData: ResultData = ResultData.fail(configProperties.messageName,
                localeMessageSourceConfiguration.getMessage(MESSAGE_ERROR_NAME))
        return resultData.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建失败检查信息 JSONObject 带  token
     *
     * @param failResult       ResultData
     *
     * @return JSONObject
     */
    protected fun initErrorCheckJSONObject(failResult: ResultData): JSONObject {
        return this.initErrorJSONObject(failResult, MESSAGE_ERROR_NAME)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建失败验证信息 JSONObject 带 token
     *
     * @param failResult       ResultData
     *
     * @return JSONObject
     */
    protected fun initErrorValidationJSONObject(failResult: ResultData): JSONObject {
        // 生成 token 并放入 session 中
        this.initJSONObjectTokenValue(failResult)
        return failResult.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------


    /**
     * 创建失败 Hibernate 验证信息 JSONObject 带 token
     *
     * @param failResult       ResultData
     * @param validationResult       String
     *
     * @return JSONObject
     */
    protected fun initErrorHibernateValidationJSONObject(failResult: ResultData,
                                                         validationResult: String): JSONObject {
        failResult.setFail()[configProperties.messageName] = this.initResult2HibernateValidation(validationResult)
        failResult.setFail()[configProperties.validationMessageName] = configProperties.validationMessageName
        // 生成 token 并放入 session 中
        this.initJSONObjectTokenValue(failResult)
        return failResult.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------


    /**
     * 创建失败提示信息 JSONObject 带 token
     *
     * @param failResult       ResultData
     * @param message       String i18n 名称
     *
     * @return JSONObject
     */
    protected fun initErrorJSONObject(failResult: ResultData, message: String): JSONObject {
        failResult.setFail()[configProperties.messageName] = localeMessageSourceConfiguration
                .getMessage(message)
        // 生成 token 并放入 session 中
        this.initJSONObjectTokenValue(failResult)
        return failResult.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建成功信息 JSONObject 带 token
     *
     * @param resultData       ResultData
     * @param message       String
     *
     * @return JSONObject
     */
    protected fun initSucceedJSONObject(resultData: ResultData, message: String): JSONObject {
        resultData.setOk()[configProperties.messageName] = localeMessageSourceConfiguration
                .getMessage(message)
        // 生成 token 并放入 session 中
        this.initJSONObjectTokenValue(resultData)
        return resultData.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建保存信息 JSONObject
     *
     * @param backId BigInteger
     *
     * @return JSONObject
     */
    protected fun initSaveJSONObject(backId: BigInteger?): JSONObject {
        return this.initJSONObject(backId, MESSAGE_ADD_INFO_SUCCEED_NAME,
                MESSAGE_ADD_INFO_FAIL_NAME, true)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建更新信息 JSONObject
     *
     * @param backId BigInteger
     *
     * @return JSONObject
     */
    protected fun initUpdateJSONObject(backId: BigInteger?): JSONObject {
        return this.initJSONObject(backId, MESSAGE_EDIT_INFO_SUCCEED_NAME,
                MESSAGE_EDIT_INFO_FAIL_NAME, true)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建删除信息 JSONObject
     *
     * @param backId BigInteger
     *
     * @return JSONObject
     */
    protected fun initDeleteJSONObject(backId: BigInteger?): JSONObject {
        return this.initJSONObject(backId, MESSAGE_DELETE_INFO_SUCCEED_NAME,
                MESSAGE_DELETE_INFO_FAIL_NAME)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建清空信息 JSONObject
     *
     * @param backId BigInteger
     *
     * @return JSONObject
     */
    protected fun initTruncateJSONObject(backId: BigInteger?): JSONObject {
        return this.initJSONObject(backId, MESSAGE_TRUNCATE_INFO_SUCCEED_NAME,
                MESSAGE_TRUNCATE_INFO_FAIL_NAME)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建恢复信息 JSONObject
     *
     * @param backId BigInteger
     *
     * @return JSONObject
     */
    protected fun initRecoverJSONObject(backId: BigInteger?): JSONObject {
        return this.initJSONObject(backId, MESSAGE_RECOVER_INFO_SUCCEED_NAME,
                MESSAGE_RECOVER_INFO_FAIL_NAME)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建生成信息 JSONObject
     *
     * @param backId BigInteger
     *
     * @return JSONObject
     */
    protected fun initGenerateJSONObject(backId: BigInteger?): JSONObject {
        return this.initJSONObject(backId, MESSAGE_GENERATE_INFO_SUCCEED_NAME,
                MESSAGE_GENERATE_INFO_FAIL_NAME, true)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 创建信息 JSONObject 带 token
     *
     * @param backId BigInteger
     * @param succeedMessage String 成功提示语 i18n 名称
     * @param failMessage String 失败提示语 i18n 名称
     * @param isToken Boolean 是否生成 token
     *
     * @return JSONObject
     */
    private fun initJSONObject(backId: BigInteger?,
                               succeedMessage: String,
                               failMessage: String,
                               isToken: Boolean = false): JSONObject {
        val message: String
        val resultData: ResultData
        // 成功
        if (null != backId && BigInteger.ZERO < backId) {
            message = succeedMessage
            resultData = ResultData.ok(configProperties.messageName,
                    localeMessageSourceConfiguration.getMessage(message))
        } else {
            // 失败
            message = failMessage
            resultData = ResultData.fail(configProperties.messageName,
                    localeMessageSourceConfiguration.getMessage(message))
        }
        // 生成 token 并放入 session 中
        if (isToken) {
            this.initJSONObjectTokenValue(resultData)
        }
        return resultData.toFastJson()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 获取 ID 值 判断是不是数值 空的话就不是数值
     *
     * @param id       String
     * @return id.toBigIntegerOrNull() BigInteger
     */
    protected fun getId(id: String): BigInteger? {
        return id.toBigIntegerOrNull()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 获取 ID 值 判断是不是数值 空的话就不是数值
     *
     * @param request       HttpServletRequest
     * @return id.toBigIntegerOrNull() BigInteger
     */
    protected fun getId(request: HttpServletRequest): BigInteger? {
        val id: String = request.getParameter("id")
        return id.toBigIntegerOrNull()
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 得到 id[] 集合
     *
     * @param request HttpServletRequest
     * @return  ArrayList<BigInteger?>
     */
    protected fun getIdArray(request: HttpServletRequest): ArrayList<BigInteger>? {
        val idArray: Array<String>? = request.getParameterValues(ID_ARRAY_PARAMETER_NAME)
        if (null == idArray || idArray.isEmpty()) {
            return null
        }
        // 转为 BigInteger数组
        return ArrayUtil.string2BigInteger(idArray)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 获取状态值 bootstrap-switch 插件的启用状态标识
     *
     * @param request       HttpServletRequest
     * @return statusStr String
     */
    protected fun getStatusStr(request: HttpServletRequest): String? {
        return request.getParameter(STATUS_STR_PARAMETER_NAME)
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 根据请求设置上个请求地址
     *
     * @param request       HttpServletRequest
     *
     */
    protected fun initRefererUrl(request: HttpServletRequest) {
        var url: String? = request.getHeader("Referer")
        var currentUrl: String = request.requestURI
        // 移除前缀
        if (currentUrl.startsWith(contextPath)) {
            currentUrl = currentUrl.removePrefix(contextPath)
        }
        currentUrl = currentUrl.substring(0,
                currentUrl.indexOf("/", currentUrl.indexOf("/") + 1))
        if (null != url && url.isNotBlank()) {
            // 如果不是登录 保存 更新 删除 地址 就设置
            val urlOld: String = url
            url = url.toLowerCase()
            if (!url.contains(configProperties.adminLoginUrlName) && !url.contains(SAVE_URL_NAME)
                    && !url.contains(UPDATE_URL_NAME)
                    && !url.contains(DELETE_URL_NAME)) {
                request.setAttribute(REFERER_URL_NAME, urlOld)
            } else if (currentUrl.isNotBlank()) {
                request.setAttribute(REFERER_URL_NAME, contextPath + currentUrl + INDEX_URL)
            } else {
                request.setAttribute(REFERER_URL_NAME, contextPath + INDEX_URL)
            }
        }
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 检验是否是开发环境
     *
     * @return  Boolean
     */
    protected fun devProfile(): Boolean {
        // 开发环境
        return profile.devProfile()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 检验图片验证码
     *
     * @param clientCode String
     * @param request HttpServletRequest
     */
    protected fun checkKaptcha(clientCode: String, request: HttpServletRequest): Boolean {
        val session: HttpSession = request.session
        val serverCode: String = session.getAttribute(Constants.KAPTCHA_SESSION_KEY) as String
        return clientCode.equals(serverCode, ignoreCase = true)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 分割验证信息字符串
     *
     * @param source 字符串
     * @return 分割后的数组
     */
    private fun convertStrToArray(source: String?): Array<String>? {
        if (null == source) {
            return null
        }
        return source.split(HibernateValidationUtil.CONNECT_CHAR.toRegex())
                .dropLastWhile { it.isEmpty() }.toTypedArray()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 根据url地址  设置页面标题
     *
     * @param url 地址
     * @param request HttpServletRequest
     */
    private fun initViewTitle(url: String, request: HttpServletRequest) {
        val rule: Rule? = ruleService.getByUrl(url)
        if (null != rule) {
            if (RuleTypeEnum.BUTTON.key == rule.type) {
                val chileRule: Rule? = rule.pid?.let { ruleService.getById2Cache(it) }
                request.setAttribute(BREAD_CRUMB_CHILE_NAME, chileRule)
                val menuRule: Rule? = chileRule?.pid?.let { ruleService.getById2Cache(it) }
                request.setAttribute(BREAD_CRUMB_MENU_NAME, menuRule)
                val urlRule: Rule? = menuRule?.pid?.let { ruleService.getById2Cache(it) }
                request.setAttribute(BREAD_CRUMB_URL_NAME, urlRule)
                request.setAttribute(BREAD_CRUMB_NAME, chileRule)
            } else {
                when {
                    RuleTypeEnum.CHILD_MENU.key == rule.type -> {
                        val menuRule: Rule? = rule.pid?.let { ruleService.getById2Cache(it) }
                        request.setAttribute(BREAD_CRUMB_MENU_NAME, menuRule)
                        val urlRule: Rule? = menuRule?.pid?.let { ruleService.getById2Cache(it) }
                        request.setAttribute(BREAD_CRUMB_URL_NAME, urlRule)
                    }
                    RuleTypeEnum.MENU.key == rule.type -> {
                        val menuRule: Rule? = rule.pid?.let { ruleService.getById2Cache(it) }
                        request.setAttribute(BREAD_CRUMB_MENU_NAME, menuRule)
                    }
                    RuleTypeEnum.URL.key == rule.type -> request.setAttribute(BREAD_CRUMB_MENU_NAME, rule)
                }
                request.setAttribute(BREAD_CRUMB_NAME, rule)
            }
            request.setAttribute(BREAD_CRUMB_TITLE_NAME, rule.title)
            request.setAttribute(HEAD_TITLE_NAME, rule.title)
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 根据模块设置 url 地址
     *
     * @param model 模块
     * @param request HttpServletRequest
     */
    private fun initModelUrl(model: String, request: HttpServletRequest) {
        val webPath: String = contextPath

        request.setAttribute(INDEX_URL_NAME, webPath + model + INDEX_URL)
        request.setAttribute(ADD_URL_NAME, webPath + model + ADD_URL)
        request.setAttribute(ADD_CHILDREN_URL_NAME, webPath + model + ADD_CHILDREN_URL)
        request.setAttribute(SAVE_URL_NAME, webPath + model + SAVE_URL)
        request.setAttribute(EDIT_URL_NAME, webPath + model + EDIT_URL)
        request.setAttribute(UPDATE_URL_NAME, webPath + model + UPDATE_URL)
        request.setAttribute(VIEW_URL_NAME, webPath + model + VIEW_URL)
        request.setAttribute(DELETE_URL_NAME, webPath + model + DELETE_URL)
        request.setAttribute(DELETE_BATCH_URL_NAME, webPath + model + DELETE_BATCH_URL)
        request.setAttribute(GENERATE_URL_NAME, webPath + model + GENERATE_URL)
        request.setAttribute(MODEL_URL_NAME, webPath + model)
        request.setAttribute(MODEL_NAME, model)
        request.setAttribute(NAV_INDEX_URL_NAME, webPath + model + INDEX_URL)
        request.setAttribute(AUTHORIZATION_URL_NAME, webPath + model + AUTHORIZATION_URL)
        request.setAttribute(AUTHORIZATION_SAVE_URL_NAME, webPath + model +
                AUTHORIZATION_SAVE_URL)
        request.setAttribute(RECYCLE_BIN_URL_NAME, webPath + model + RECYCLE_BIN_URL)
        request.setAttribute(RECOVER_URL_NAME, webPath + model + RECOVER_URL)
        request.setAttribute(RECOVER_BATCH_URL_NAME, webPath + model + RECOVER_BATCH_URL)
        request.setAttribute(UPDATE_PASSWORD_URL_NAME, webPath + model + UPDATE_PASSWORD_URL)
        request.setAttribute(UPDATE_NICK_NAME_URL_NAME, webPath + model + UPDATE_NICK_NAME_URL)
        request.setAttribute(TRUNCATE_URL_NAME, webPath + model + TRUNCATE_URL)
        request.setAttribute(RUN_URL_NAME, webPath + model + RUN_URL)
        request.setAttribute(PAUSE_URL_NAME, webPath + model + PAUSE_URL)
        request.setAttribute(RESUME_URL_NAME, webPath + model + RESUME_URL)

    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 得到当前管理员
     *
     * @return  User
     */
    protected fun getCurrentAdmin(): User? {
        return ShiroSessionUtil.getAttribute(configProperties.adminSessionName) as User?
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 生成 token 并放入 session 中
     *
     */
    protected fun initJSONObjectTokenValue(result: ResultData) {
        // 生成 token 并放入 session 中
        val tokenValue: String = this.initTokenValue()
        result["formToken"] = tokenValue
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 生成 token 并放入 session 中
     *
     */
    private fun initTokenValue(): String {
        // 新的 token
        val tokenValue: String = UUID.randomUUID().toString()
        ShiroSessionUtil.setAttribute(shareProperties.formToken, tokenValue)
        return tokenValue
    }

    // -----------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End BaseAdminController class

/* End of file BaseAdminController.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/admin/common/controller/BaseAdminController.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------
